<template>
    <div>
        <n-grid :x-gap="24">
            <n-grid-item span="10">
              <n-card>
              <n-form :label-width="100" label-placement="left" :model="mjPrompt" :rules="rules" ref="formRef">
                <n-divider title-placement="left">
                  参考图
                </n-divider>
                  <n-icon v-if="mjPrompt.base64" class="n-icon" @click="resetImg">
                    <Ban></Ban>
                  </n-icon>
                <n-form-item>
                  <n-image style="display: block;margin: 0 auto;" width="300" object-fit="cover" v-if="mjPrompt.base64" :src="mjPrompt.base64"></n-image>
                </n-form-item>
                  <n-empty v-if="!mjPrompt.base64" description="未上传图片">
                  <template #extra>
                    <n-upload
                    :custom-request="customRequest"
                    >
                      <n-button >上传图片</n-button>
                    </n-upload>
                  </template>
                </n-empty>
                <n-divider title-placement="left">
                  提示词
                </n-divider>
                <n-form-item path="prompt">
                  <n-input v-model:value="mjPrompt.prompt"  type="textarea" style="height: 100px"/>
                  <n-button type="info" @click="promptDrawerShow = !promptDrawerShow" style="height: 100px;margin-left:5px;">
                    提示词库
                  </n-button>
                </n-form-item>
                <div>
                    <n-space aria-placeholder="right">
                        <n-button ghost>
                            重置
                        </n-button>
                        <n-button type="primary" @click="formSubmit" ghost>
                            生成
                        </n-button>
                    </n-space>
                </div>
              </n-form>
              </n-card>
            </n-grid-item>
            <n-grid-item span="14">
              <n-spin :show="recordLoading">
                <n-card style=" height: calc(100vh - 230px);overflow-y: auto;display: flex;">
                    <n-form
                        label-placement="left"
                        require-mark-placement="right-hanging"
                    >
                      <n-form-item label="显示类型:" >
                          <n-switch v-model:value="promptViewType" size="large">
                              <template #unchecked>
                                  标签
                              </template>
                              <template #checked>
                                  文字
                              </template>
                          </n-switch>
                      </n-form-item>
                    </n-form>
                  <n-list hoverable clickable>
                    <n-list-item v-for="task in taskList">
                        <n-thing :title="mjActionMap.get(task.taskType)" :title-extra="dayjs(task.startTime).format('YYYY-MM-DD HH:mm:ss')">
                           <n-spin size="large" :show="task.status !== 'SUCCESS' && task.status!=='FAILURE'">
                            <n-grid :x-gap="24">
                                <n-grid-item span="12">
                                    <n-alert v-if="task.status === 'FAILURE'" title="生成错误" type="error">
                                        {{task.failReason}}
                                    </n-alert>
                                   <n-alert v-if="task.status === 'IN_PROGRESS'" title="生成进度" type="info">
                                        {{task.progress}}
                                   </n-alert>
                                    <n-tabs style="height: 300px;" animated >
                                      <n-tab-pane style="overflow-y: auto;" name="promptEn" tab="提示词">
                                        <n-space>
                                          <text v-if="promptViewType"> {{task.promptEn}}</text>
                                          <n-tag
                                              style="white-space: pre-wrap;height: auto;padding:5px 5px 5px 5px"
                                              v-if="!promptViewType && task.promptEn && task.promptEn.length > 0"
                                              v-for="(prompt,index) in task.promptEn.split(',')"
                                              :type="index%5===1?'default':index%5===2?'primary':index%5===3?'info':index%5===4?'success':'warning'"
                                          >
                                            {{prompt}}
                                          </n-tag>
                                        </n-space>
                                      </n-tab-pane>
                                      <n-tab-pane name="prompt" tab="提示词中文" v-if="task.prompt && task.prompt != task.promptEn">
                                        <n-space  v-if="task.prompt">
                                            <text v-if="promptViewType"> {{task.prompt}}</text>
                                            <n-tag
                                                style="white-space: pre-wrap;height: auto;padding:5px 5px 5px 5px"
                                                v-if="!promptViewType && task.prompt != task.promptEn"
                                                v-for="(prompt,index) in task.prompt.split(',')"
                                                :type="index%5===1?'default':index%5===2?'primary':index%5===3?'info':index%5===4?'success':'warning'">{{prompt}}</n-tag>
                                        </n-space>
                                      </n-tab-pane>
                                      <n-tab-pane name="promptImage" tab="参考图" v-if="task.promptImagesUrl">
                                        <n-image :width='200' :src="fileFunction.getViewFilePathByUserFileId(task.promptImagesUrl)"></n-image>

                                      </n-tab-pane>
                                </n-tabs>
                                  <n-space>
                                    <n-button-group name="upscale" v-if=" (task.taskType === 'MJ_IMAGINE' || task.taskType==='MJ_VARIATION') && task.status === 'SUCCESS'">
                                      <n-popconfirm
                                          :show-icon="false"
                                          :negative-text="null"
                                          @positive-click="handleUpscale(1,task.id)"
                                      >
                                        <template #trigger>
                                          <n-button>U1</n-button>
                                        </template>
                                        <span>确定放大左上角照片吗?</span>
                                      </n-popconfirm>

                                      <n-popconfirm
                                          :show-icon="false"
                                          :negative-text="null"
                                          @positive-click="handleUpscale(2,task.id)"
                                      >
                                        <template #trigger>
                                          <n-button>U2</n-button>
                                        </template>
                                        <span>确定放大右上角照片吗?</span>
                                      </n-popconfirm>

                                      <n-popconfirm
                                          :show-icon="false"
                                          :negative-text="null"
                                          @positive-click="handleUpscale(3,task.id)"
                                      >
                                        <template #trigger>
                                          <n-button>U3</n-button>
                                        </template>
                                        <span>确定放大左下角照片吗?</span>
                                      </n-popconfirm>

                                      <n-popconfirm
                                          :show-icon="false"
                                          :negative-text="null"
                                          @positive-click="handleUpscale(4,task.id)"
                                      >
                                        <template #trigger>
                                          <n-button>U4</n-button>
                                        </template>
                                        <span>确定放大右下角照片吗?</span>
                                      </n-popconfirm>
                                    </n-button-group>
                                  </n-space>
                                </n-grid-item>
                                <n-grid-item span="12">
                                    <n-image lazy="true" style="display: flex; justify-content: center;"  width="300" :src="task?.imageUrl?.startsWith('http')?task.imageUrl:fileFunction.getViewFilePathByUserFileId(task.imageUrl)">
                                    </n-image>
                                </n-grid-item>
                            </n-grid>
                           </n-spin>
                        </n-thing>
                    </n-list-item>
                  </n-list>
                </n-card>
              </n-spin>
            </n-grid-item>
      </n-grid>

      <n-drawer v-model:show="promptDrawerShow" :width="drawerWidth">
        <n-drawer-content title="提示词选择器" closable>
          <promptTemplate prompt="8k" negative-prompt="low quality" code="02" @loadPrompt-event="loadPromptEvent"></promptTemplate>
        </n-drawer-content>
      </n-drawer>
    </div>
</template>

<script setup lang="ts">
import {onMounted, reactive, ref} from 'vue';
import {UploadCustomRequestOptions, useMessage} from 'naive-ui';
import {mjControllerApi} from '@/api/mj/mjController.api'
import {Ban} from '@vicons/ionicons5'
import Text from "@/views/chat/components/Message/Text.vue"
import fileFunction from '@/libs/globalFunction/file.js'
import dayjs from 'dayjs'
import promptTemplate from "@/components/prompt/promptTemplate.vue"


const checked = ref(false)
const formRef: any = ref(null);
const message = useMessage();
const imageSrc = ref(); // 默认图片的URL
const mjPrompt  =  reactive({
    prompt: '',
    base64: ''
});

const promptViewType = ref(false)
const recordLoading = ref(false)
const taskList = ref([])

const promptDrawerShow = ref(false)
const drawerWidth = ref(0)

const mjActionMap = new Map([
  ['MJ_IMAGINE', '想象'],
  ['MJ_UPSCALE', '放大'],
  ['MJ_VARIATION', '变换'],
  ['MJ_DESCRIBE', '描述图片'],
  ['MJ_BLEND', '混合']
])


const rules = {
  prompt: {
    required: true,
    message: '请输入提示词',
    trigger: 'submit',
  }
};



const customRequest = (uploadOption:UploadCustomRequestOptions) => {
  const reader = new FileReader();
  //@ts-ignore
  reader.readAsDataURL(uploadOption.file.file);
  reader.onloadend = () => {
    //@ts-ignore
    mjPrompt.base64 = reader.result
  };
}

/**重置图片*/
const resetImg = () =>{
  mjPrompt.base64 = ''
}

/**初始化事件**/
onMounted(() => {
  // 设置当前drawerWidth 宽度
  drawerWidth.value = window.innerWidth - 300;
  window.addEventListener('resize', handleResize);
  getPaintRecord()
})

// 窗口宽度变化
const handleResize = () => {
  drawerWidth.value = window.innerWidth - 300;
}


const loadPromptEvent = (prompt:string,negativePrompt:string) => {
  mjPrompt.prompt = prompt;
  promptDrawerShow.value = false;
}

/**提交任务**/
const formSubmit =  async () => {
  const res = await mjControllerApi.imagine(mjPrompt)
  if(res.code === 200 ){
    const data = res.data
    if(data.code ===1 ){
      // 提交成功
      message.success('提交成功')
      const newTask = ref({
        id : data.result,
        status: 'NOT_STARTED',
        taskType: 'MJ_IMAGINE',
      })
      taskList.value.unshift(newTask.value)
      checkTask(data.result)
    }else {
      if(data.code === '22'){
        message.info('排队中')
      }else if(data.code==='21'){
        message.info('已存在')
      }else{
        message.error('业务错误,请稍后再试')
      }
    }
  }else {
    message.error(res.msg)
  }
}


let timeoutId = ref();// 保存当前的 setTimeout 的 id
const checkTask = async (taskId:string) => {
  const {data} = await mjControllerApi.checkTask(taskId)
  // 更新list
  const index = taskList.value.findIndex((item:any) => item.id === taskId)
  taskList.value[index] = data
  if(data.status == 'SUCCESS') {
    imageSrc.value = data.imageUrl;
    clearTimeout(timeoutId.value);
    await getPaintRecord()
  }else if(data.status == 'FAILURE'){
    clearTimeout(timeoutId.value);
  }else {
    timeoutId.value = setTimeout(() => {
      checkTask(taskId);
    }, 2000); // 每隔0.5秒调用一次 checkTask
    if(data.status == "IN_PROGRESS"){
      imageSrc.value = data.imageUrl
    }
  }
}


/***点击按钮*/
const handleUpscale = (index:number,taskId:string) => {
  mjControllerApi.change({
    'taskId': taskId,
    'action': 'MJ_UPSCALE',
    'index': index
  }).then(res=>{
    if(res.code===200){
      const data = res.data
      if(data.code ===1 ){
        // 提交成功
        message.success('提交成功')
        const newTask = ref({
          id : data.result,
          status: 'NOT_STARTED',
          taskType: 'MJ_UPSCALE',
        })
        taskList.value.unshift(newTask.value)
        checkTask(data.result)
      }else {
        if(data.code === '22'){
          message.info('排队中')
        }else if(data.code==='21'){
          message.info('已存在')
        }else{
          message.error('业务错误,请稍后再试')
        }
      }
    }else {
      message.error(res.msg)
    }
  })
};


/**
 * 获取当前登录人的绘画记录
 */
const getPaintRecord = async () =>{
  recordLoading.value = true
  const res = await mjControllerApi.getPaintRecords()
  recordLoading.value = false
  if(res.code === 200){
      taskList.value = res.data
      taskList.value.forEach((item:any)=>{
        if(item.status!=='SUCCESS'){
          checkTask(item.id)
        }
      })
  }else {
      message.error(res.msg)
  }
}
</script>
<style>
.n-icon {
  float: right;
}
</style>
